package swingFiles;

import javax.swing.JPanel;
import java.awt.Color;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
import javax.swing.JTextField;
import javax.swing.JComboBox;
import javax.swing.JButton;

import mainFiles.Class;
import mainFiles.GmsDB;
import mainFiles.Instructor;
import mainFiles.Location;

/**
 * Creates the panel which allows users to create a class in the database
 * 
 * @author Emily Linniman
 * @version December 1, 2014
 */
@SuppressWarnings("serial")
public class CreateClassPanel extends JPanel {
	
	/** The field to input the class id. */
	private JTextField classIdField;
	
	/** The field to input the class size limit. */
	private JTextField sizeLimitField;
	
	/** The field to input the days the class takes place. */
	private JTextField daysField;
	
	/** The field to input the time the class takes place. */
	private JTextField timeField;
	
	/** The field to input the cost of the class. */
	private JTextField costField;
	
	/** The field to input the description of the class. */
	private JTextField descriptionField;
	
	/** The field to input the name of the class. */
	private JTextField classNameField;
	
	/** The database object which interacts with the gym management system database. */
	private GmsDB db;
	
	/** The frame the panel is placed on. */
	private JFrame my_frame;

	/**
	 * Create the panel.
	 * @throws SQLException 
	 */
	public CreateClassPanel(JFrame the_frame, final JPanel previous_panel) throws SQLException {
		my_frame = the_frame;

		db = new GmsDB();
		setBackground(Color.ORANGE);
		setLayout(null);
		
		JLabel headerLabel = new JLabel("Create A Class");
		headerLabel.setHorizontalAlignment(SwingConstants.CENTER);
		headerLabel.setFont(new Font("Arial", Font.PLAIN, 18));
		headerLabel.setBounds(17, 6, 187, 16);
		add(headerLabel);
		
		JLabel idLabel = new JLabel("Class ID");
		idLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		idLabel.setBounds(57, 40, 89, 16);
		add(idLabel);
		
		classIdField = new JTextField();
		classIdField.setHorizontalAlignment(SwingConstants.CENTER);
		classIdField.setBounds(269, 34, 134, 28);
		add(classIdField);
		classIdField.setColumns(9);
		
		JLabel nameLabel = new JLabel("Name");
		nameLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		nameLabel.setBounds(57, 92, 104, 16);
		add(nameLabel);
		
		JLabel instructorLabel = new JLabel("Instructor");
		instructorLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		instructorLabel.setBounds(57, 68, 114, 16);
		add(instructorLabel);
		
		final JComboBox instructorComboBox = new JComboBox();
		instructorComboBox.addItem(" ");
		List<Instructor> instructorList = db.getInstructors();
		for (int i = 0; i < instructorList.size(); i++) {
			instructorComboBox.addItem(instructorList.get(i).getID());
		}
		instructorComboBox.setFont(new Font("Arial", Font.PLAIN, 15));
		instructorComboBox.setBounds(269, 64, 134, 27);
		add(instructorComboBox);
		
		JLabel timeLabel = new JLabel("Time");
		timeLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		timeLabel.setBounds(57, 197, 104, 16);
		add(timeLabel);
		
		final JComboBox locationComboBox = new JComboBox();
		locationComboBox.addItem(" ");
		List<Location> locationList = db.getLocations();
		for (int i = 0; i < locationList.size(); i++) {
			locationComboBox.addItem(locationList.get(i).getLocationID());
		}
		locationComboBox.setFont(new Font("Arial", Font.PLAIN, 15));
		locationComboBox.setBounds(269, 116, 134, 27);
		add(locationComboBox);
		
		JLabel locationLabel = new JLabel("Location");
		locationLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		locationLabel.setBounds(57, 120, 104, 16);
		add(locationLabel);
		
		JLabel sizeLimitLabel = new JLabel("Size Limit");
		sizeLimitLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		sizeLimitLabel.setBounds(57, 143, 114, 16);
		add(sizeLimitLabel);
		
		sizeLimitField = new JTextField();
		sizeLimitField.setHorizontalAlignment(SwingConstants.CENTER);
		sizeLimitField.setBounds(269, 137, 134, 28);
		add(sizeLimitField);
		sizeLimitField.setColumns(3);
		
		JLabel daysLabel = new JLabel("Days");
		daysLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		daysLabel.setBounds(57, 169, 61, 16);
		add(daysLabel);
		
		daysField = new JTextField();
		daysField.setHorizontalAlignment(SwingConstants.CENTER);
		daysField.setBounds(269, 163, 134, 28);
		add(daysField);
		daysField.setColumns(20);
		
		timeField = new JTextField();
		timeField.setHorizontalAlignment(SwingConstants.CENTER);
		timeField.setBounds(269, 191, 134, 28);
		add(timeField);
		timeField.setColumns(5);
		
		JLabel costLabel = new JLabel("Cost");
		costLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		costLabel.setBounds(57, 225, 61, 16);
		add(costLabel);
		
		costField = new JTextField();
		costField.setHorizontalAlignment(SwingConstants.CENTER);
		costField.setBounds(269, 219, 134, 28);
		add(costField);
		costField.setColumns(5);
		
		JLabel descriptionLabel = new JLabel("Description");
		descriptionLabel.setFont(new Font("Arial", Font.PLAIN, 15));
		descriptionLabel.setBounds(57, 253, 89, 16);
		add(descriptionLabel);
		
		descriptionField = new JTextField();
		descriptionField.setBounds(269, 247, 134, 47);
		add(descriptionField);
		descriptionField.setColumns(160);
		
		JButton createButton = new JButton("Create Class");
		createButton.setFont(new Font("Arial", Font.PLAIN, 15));
		createButton.setBounds(201, 2, 117, 29);
		createButton.addActionListener(new ActionListener() {
			
			//Checks validity of the data input
			//If all data is valid, creates the class in the database
			//If data is not valid, shows error message
			public void actionPerformed(ActionEvent arg0) {
				boolean success = true;
				String failedElement = null;
				
				String id = classIdField.getText();
				if (id.length() != 9 || !isNumber(id)) {
					success = false;
					failedElement = "ID";
				}
				boolean foundID = false;
				try {
					List<Class> classes = db.getClasses();
					for (Class currClass : classes) {
						if (currClass.getID() == id)
							foundID = true;
					}
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
				if (foundID) {
					success = false;
					failedElement = "ID";
				}
				
				String name = classNameField.getText();
				if (name.length() > 25 || name.length() < 1) {
					success = false;
					failedElement = "Name";
				}
				
				String sizeString = sizeLimitField.getText();
				int size = 0;
				if (!isInteger(sizeString)) {
					success = false;
					failedElement = "Size";
				} else {
					size = Integer.parseInt(sizeLimitField.getText());
				}
				
				String days = daysField.getText();
				if (!isDate(days)) {
					success = false;
					failedElement = "Date";
				}
				String time = timeField.getText();
				if (!isTime(time)) {
					success = false;
					failedElement = "Time";
				}
				
				String description = descriptionField.getText();
				if (description.length() > 160) {
					success = false;
					failedElement = "Description";
				}
				
				String costString = costField.getText();
				BigDecimal cost;
				if (!isNumber(costString)) {
					success = false;
					cost = null;
					failedElement = "Cost";
				} else {
					Double tmp = Double.valueOf(costField.getText());
					cost = BigDecimal.valueOf(tmp);
				}
				
				String location = (String)locationComboBox.getSelectedItem();
				String instructor = (String)instructorComboBox.getSelectedItem();
				if (location == " ") {
					success = false;
					failedElement = "Location";
				} else if (instructor == " ") {
					success = false;
					failedElement = "Instructor";
				}
				
				if (success) {
					Class newClass = new Class(id, name, size, cost, days, time, description, instructor, location);
					db.addClass(newClass);
					JOptionPane.showMessageDialog(my_frame, "Class sucessfully added!", "Sucess!", JOptionPane.PLAIN_MESSAGE);
				} else {
					JOptionPane.showMessageDialog(my_frame, "Class add failed. Please enter a valid " + failedElement, "Error!", JOptionPane.ERROR_MESSAGE);
				}
			}
		});
		add(createButton);
		
		JButton btnBack = new JButton("Back");
		btnBack.setBounds(327, 2, 117, 29);
		btnBack.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				my_frame.setContentPane(previous_panel);
				my_frame.validate();
				my_frame.setVisible(true);
			}
		});
		add(btnBack);
		
		classNameField = new JTextField();
		classNameField.setHorizontalAlignment(SwingConstants.CENTER);
		classNameField.setBounds(269, 86, 134, 28);
		add(classNameField);
		classNameField.setColumns(25);

	}
	
	/**
	 * Checks to see if the given string is a number
	 * @param st the string to check if it is a number
	 * @return true if the string is a number, false otherwise
	 */
	private boolean isNumber(String st) {
		boolean success = true;
		try {
			Double.parseDouble(st);
		}
		catch(NumberFormatException e) {
			success = false;
		}
		return success;
	}
	
	/**
	 * Checks to see if the given string is an integer
	 * @param st the string to check if it is a string
	 * @return true if the string is an integer, false otherwise
	 */
	private boolean isInteger(String st) {
		boolean success = true;
		try {
			Integer.parseInt(st);
		}
		catch(NumberFormatException e) {
			success = false;
		}
		return success;
	}
	
	/**
	 * Checks if the string given is a valid date.
	 * 
	 * @param date the string to check for validity
	 * @return true if the date is valid, false otherwise
	 */
	private boolean isDate(String date) {
		try {
			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			dateFormat.setLenient(false);
			dateFormat.parse(date);	
			return true;
		} catch (ParseException e) {
			return false;
		}
	}
	
	/**
	 * Checks to see if the string given is a valid time.
	 * 
	 * @param time the string to check for validity
	 * @return true if the time is valid, false otherwise
	 */
	private boolean isTime(String time) {
		try {
			DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
			timeFormat.setLenient(false);
			timeFormat.parse(time);
			return true;
		} catch(ParseException e) {
			return false;
		}
	}
}
